import simplejson
import urllib
from zope.interface import implements
from zope.component import getMultiAdapter, getUtility, adapts
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.interfaces import IPloneSiteRoot
from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from plone.memoize import view
from collective.virtualtreecategories.browser.interfaces import IVirtualTreeCategoriesSettingsView
from collective.virtualtreecategories.interfaces import IVirtualTreeCategoryConfiguration
from collective.virtualtreecategories import VTCMessageFactory as _
from zope.i18n import translate
import logging
from plone.app.layout.viewlets import ViewletBase

logger = logging.getLogger('vtc-catview')


class CategoryTreeSettingsView(BrowserView):
    """implements(IVirtualTreeCategoriesSettingsView)
    adapts(IPloneSiteRoot)"""

         

    


class CategoryKeywords(BrowserView):

    @view.memoize_contextless
    def tools(self):
        """ returns tools view. Available items are all portal_xxxxx
            For example: catalog, membership, url
            http://dev.plone.org/plone/browser/plone.app.layout/trunk/plone/app/layout/globals/tools.py
        """
        return getMultiAdapter((self.context, self.request), name=u"plone_tools")

    def _category_path_from_request(self, path=None):
        if path is None:
            category_path = self.request.form.get('category_path')
        else:
            category_path = path
        if not category_path:
            return []
        if isinstance(category_path, basestring):
            category_path = category_path.split(',')
        category_path.reverse()
        # omit root node
        category_path = category_path and category_path[1:]
        return category_path

    def get_category_keywords(self):
        self.request.response.setHeader('Content-Type', 'application/json; charset=utf-8')
        portal = getUtility(IPloneSiteRoot)
        category_path = self._category_path_from_request()
        if not category_path:
            kws = []
        else:
            kws = IVirtualTreeCategoryConfiguration(portal).list_keywords(category_path, recursive=False)
        return simplejson.dumps(dict(keywords=kws))

    def save_category_keywords(self):
        portal = getUtility(IPloneSiteRoot)
        category_path = self._category_path_from_request()
        kws = self.request.form.get('kws', [])
        if isinstance(kws, basestring):
            kws = kws.split(',')
        if not category_path:
            return 'No valid category selected'
        logger.info('Going to save %d keywords to category %r' % (len(kws), category_path))
        IVirtualTreeCategoryConfiguration(portal).set(category_path, kws)
        self.request.response.setHeader('Content-Type', 'text/plain; charset=utf-8')
        return simplejson.dumps(dict(
                                    message=translate(_('Category saved'), context=self.request),
                                    keywords=kws
                                    ))

    def categories_tree(self):
        self.request.response.setHeader('Content-Type', 'application/json; charset=utf-8')
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        # inject root node
        root = dict(
          attributes={'id': "root-node", 'rel': 'root'},
          state="open",
          data=translate(_("Root node"), context=self.request),
          children=storage.category_tree()
         )
        return simplejson.dumps(root)

    def category_added_renamed(self):
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        old_id = self.request.form.get('old_id')
        new_name = self.request.form.get('new_name')
        if not new_name:
            return 'Missing new name.'
        if not old_id:
            # create new node
            # strip last element from category_path, because it is newly created category name which does not exist yet
            category_path = self._category_path_from_request()[:-1]
            new_id = storage.add_category(category_path, new_name)
            if new_id:
                result = simplejson.dumps(dict(
                                           msg=translate(_(u'Category created'), context=self.request),
                                           new_id=new_id,
                                           result=True))
            else:
                result = simplejson.dumps(dict(
                                           msg=translate(_(u'Category creation error!'), context=self.request),
                                           new_id='',
                                           result=False))
        else:
            # rename old node
            category_path = self._category_path_from_request()
            new_id = storage.rename_category(category_path, old_id, new_name)
            if new_id:
                result = simplejson.dumps(dict(
                                               msg=translate(_(u'Category renamed'), context=self.request),
                                               new_id=new_id,
                                               result=True))
            else:
                result = simplejson.dumps(dict(
                                               msg=translate(_(u'Could not rename category.'), context=self.request),
                                               new_id='',
                                               result=False))
        return result

    def category_removed(self):
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        category_path = self._category_path_from_request()
        if not category_path:
            msg = translate(_(u"You can't remove root category. Please reload page."), context=self.request),
            result = False
        else:
            result = storage.remove_category(category_path)
            if result:
                msg = translate(_(u'Category removed.'), context=self.request),
            else:
                msg = translate(_(u'Could not remove category. Please reload page.'), context=self.request),
        return simplejson.dumps(dict(msg=msg, result=result))

    def search_content_by_keywords(self):
        """
        Attempting to search the catalog
        """
        catalog = self.context.portal_catalog
        kw_keys = catalog.uniqueValuesFor('Subject')
        query = {}
        query['Subject'] = kw_keys
        
        logger.info("2-Searching: %", query.__str__())
        
        results = catalog.searchResults(query)
        return results
        
    def fetch_contents_by_keyword(self):
        """
        Returns the actual search results
        """
        
        catalog_results = []
        results = {}
        
        sel_kw = self.request.form.get('keyword')
        
        if sel_kw is not None:
            for brain in self.context.portal_catalog.searchResults(Subject=(sel_kw)):
                catalog_results.append({
                    'id' : brain.getId,
                    'uid' : brain.UID,
                    'url' : brain.getURL(),
                    'portal_type' : brain.portal_type,
                    'title' : brain.Title == "" and brain.id or brain.Title,
                    'icon' : brain.getIcon,
                    'description' : brain.Description
                    })
                    
        # add catalog_results
        results['items'] = catalog_results
        
        # Return results in JSON format
        return simplejson.dumps(results)
        
    def fetch_contents_by_category(self):
        category = self.request.form.get('category')
        
        portal_catalog = getToolByName(self, 'portal_catalog')
        query = {}
        query['resourcecategorypath '] = category # Does not seem to work
        
        results = portal_catalog.searchResults(query)
        results_list = []
        content_results = {}
        
        # Check if the object is tagged with the given category
        for brain in results:
            if hasattr(brain, 'resourcecategorypath'):
                cat_path = str(brain.resourcecategorypath)
                if cat_path is not '':
                    if category.lower() in cat_path.lower(): 
                        results_list.append({
                            'id' : brain.getId,
                            'uid' : brain.UID,
                            'url' : brain.getURL(),
                            'portal_type' : brain.portal_type,
                            'title' : brain.Title == "" and brain.id or brain.Title,
                            'icon' : brain.getIcon,
                            'description' : brain.Description
                            })
                            
        # add catalog_results
        content_results['items'] = results_list
        
        # Return results in JSON format
        return simplejson.dumps(content_results)
        
    def list_keywords_by_categories(self):
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        # categories - list of lists where the sublist is category_path
        """categories = self.request.form.get('categories', [])
        # list of keywords already assigned to the content
        selected = self.request.form.get('selected', [])
        
        logger.info('CATEGORIES: %s' % (categories))
        logger.info('SELECTED: %s' % (selected))

        if isinstance(categories, basestring):
            categories = [categories]
        if isinstance(selected, basestring):
            selected = [selected]
        result = set()
        if categories:
            for category in categories:
                path = self._category_path_from_request(category)
                result.update(storage.list_keywords(path, recursive=False))
        else:
            result = set(self.tools().catalog().uniqueValuesFor('Subject'))
            sorted(result)"""
            
        # Added code
        result = set()
        result = set(self.tools().catalog().uniqueValuesFor('Subject'))
        # End of added code
        
        result = result.difference(selected)
        return simplejson.dumps(dict(keywords=list(result)))

    def get_content_count(self, kw):
        kw = urllib.unquote_plus(kw)
        count = len(self.tools().catalog().searchResults(Subject=kw))
        print kw, count
        return count
        
    def traverse_cat(self, cat_node, storage, kword): 
        node_path = ' > '  
        category_nodes = storage.list_categories(cat_node.path)          
        for node in category_nodes:     
            try: 
                if kword in storage.list_keywords(node.path, recursive=True):
                    print node, 'Got keyword'
                    node_path += node.title
                    node_path += self.traverse_cat(node, storage, kword)
            except AttributeError:
                print node, 'ERROR: No path attribute defined.'
        return node_path
        
    
    def get_full_path(self, kword):
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        category_nodes = storage.list_categories("/")
        full_path = ''
        for node in category_nodes:
            if kword in storage.list_keywords(node.path, recursive=True):
                full_path += node.title
                full_path += self.traverse_cat(node, storage, kword)        
                
        return full_path
        
class CategoryKeywordsDisplay(ViewletBase):

    def traverse_cat(self, cat_node, storage, kword): 
        node_path = ' > '  
        category_nodes = storage.list_categories(cat_node.path)          
        for node in category_nodes:     
            try: 
                if kword in storage.list_keywords(node.path, recursive=True):
                    print node, 'Got keyword'
                    node_path += node.title
                    node_path += self.traverse_cat(node, storage, kword)
            except AttributeError:
                print node, 'ERROR: No path attribute defined.'
        return node_path
        
    
    def get_full_path(self, kword):
        storage = IVirtualTreeCategoryConfiguration(getUtility(IPloneSiteRoot))
        category_nodes = storage.list_categories("/")
        full_path = ''
        for node in category_nodes:
            if kword in storage.list_keywords(node.path, recursive=True):
                full_path += node.title
                full_path += self.traverse_cat(node, storage, kword)        
                
        return full_path
        
    def getPath(self, path):
        """Used in the apkn.virtualtreecategories product to split path"""
        catpathlinks = []
        pathlist = str(path).split(";")
        for apath in pathlist:
            catlist = apath.split('->')
            catlinks = []
            for category in catlist:
                catlinks.append(category.strip())
            catpathlinks.append(catlinks)
        return catpathlinks
        
    def display_category_path(self, catContext):
        currObj = catContext

